﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Configuration;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using NHibernate;
using Configuration=NHibernate.Cfg.Configuration;

namespace Epona.NHibernateRepository
{
    public static class SessionFactoryConfiguration
    {
        private static string ConfigurationAssemblyPath = ConfigurationManager.AppSettings["ConfigurationAssemblyPath"];
        private static string SerialzedFilePath = ConfigurationManager.AppSettings["SerialzedFilePath"];
        private static Configuration configuration;
        public static ISessionFactory SesssionFactory { private set; get; }
        
        public static bool IsConfigurationFileValid
        {
            get
            {
                try
                {
                    Assembly assembly = Assembly.Load(ConfigurationAssemblyPath);
                    FileInfo configInfo = new FileInfo(SerialzedFilePath);
                    FileInfo asmInfo = new FileInfo(assembly.Location);
                    return configInfo.LastWriteTime >= asmInfo.LastWriteTime;
                }
                catch
                {
                    return false;
                }
            }
        }
        public static Configuration ConfigureNHibernate(string assembly)
        {
            configuration = LoadConfigurationFromFile();
            if(configuration==null)
            {
                configuration = new Configuration();
                configuration.AddAssembly(assembly);
                FileStream file = File.Open(SerialzedFilePath, FileMode.Create);
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(file, configuration);
                file.Close();
            }

            return configuration;
        }

        private static Configuration LoadConfigurationFromFile()
        {
            if (!IsConfigurationFileValid) return null;
            try
            {
                using(FileStream file=File.Open(SerialzedFilePath,FileMode.Open))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    return bf.Deserialize(file) as Configuration;
                }
            }
            catch
            {
                return null;
            }
        }

        public static void Initialize()
        {
            configuration = ConfigureNHibernate(ConfigurationAssemblyPath);
            SesssionFactory = configuration.BuildSessionFactory();
        }
    }
}
